home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#21 (Jun 87)
/
format source
/
Format.a
< prev
next >
Wrap
Text File
|
1987-05-07
|
20KB
|
754 lines
;************************ File: Format.a ***********************
;***************************************************************
;
; A formatting program to perform low level formatting of a SCSI
; hard disk. Allows user to enter disk drive parameters and
; information about defects. This file contains all the standard
; code for Menus etc. It also contains the procedures for error
; handling.
BLANKS ON
INCLUDE 'FormatEqu.a'
LOAD 'Traps.d'
LOAD 'ToolEqu.d'
LOAD 'SysEqu.d'
LOAD 'QuickEqu.d'
LOAD 'SCSIEqu.d'
LOAD 'PackMacs.d'
; Note Export directives must be placed before a symbol is
; declared.
EXPORT (DialogBuff,QuickDraw,ButtonHit,DialogPort):DATA
EXPORT (ItemType,ItemHandle,ItemRect,MyPort):DATA
EXPORT (StrBuff1,StrBuff2,StrBuff3,StrBuff4):DATA
AppleMH ds.l 1 ;handle for Apple menu
FileMH ds.l 1 ;handle for File menu
EditMH ds.l 1 ;handle for Edit menu
SCSIMH ds.l 1 ;handle for SCSI menu
DAName ds.b 255 ;space for DA's name
Window ds.l 1
DialogBuff ds.l DialWLen
MyPort ds.l 1
ButtonHit ds.w 1
DialogPort ds.l 1
ItemType ds.l 1
ItemHandle ds.l 1
ItemRect ds.l 2
StrBuff1 ds.b StrBuffLen
StrBuff2 ds.b StrBuffLen
StrBuff3 ds.b StrBuffLen
StrBuff4 ds.b StrBuffLen
EventRec RECORD 20, INCR
what ds.w 1 ;
Message ds.l 1 ;
When ds.l 1 ;
Point ds.l 1 ;
Modify ds.w 1 ;
ENDR
; Note: The space for quickdraw globals must be declared.
; Unlike MDS, the MPW assembler does not do it for you.
QuickDraw RECORD ,DECREMENT
thePort ds.l 1
ORG -grafSize
ENDR
; This is our program.
Begin MAIN
ALIGN 2
IMPORT (InitManagers,LoadMenu,InitGlobals,EventLoop):CODE
;we must import these symbols as they are not
;yet defined in this file.
jsr InitManagers
jsr LoadMenu
jsr InitGlobals
jmp EventLoop
ENDMAIN
; PROC InitManagers
;
; Initialize all managers that we might need.
InitManagers PROC ENTRY
IMPORT QuickDraw:DATA
pea QuickDraw.thePort(A5)
_InitGraf
_InitFonts
move.l #AllEvents,D0
_FlushEvents
_InitWindows
_InitMenus
clr.l -(A7)
_InitDialogs
_TEInit
_InitCursor
rts
ENDPROC
; PROC LoadMenus
;
; Subroutine called at start up time to load our menus onto the
; heap, instal them and then draw the menu bar.
LoadMenu PROC ENTRY
clr.l -(A7)
move.w #AppleM,-(A7) ;"About..." menu ID for Apple menu
_GetRMenu ;load it on heap
move.l (A7),AppleMH(A5) ;copy handle for future ref.
move.l (A7),-(A7) ;duplicate handle for the next 2 traps
clr.w -(A7) ;
_InsertMenu
move.l #'DRVR',-(A7) ;get desk accessories
_AddResMenu ;add to Apple Menu
clr.l -(A7) ;space for next handle
move.w #FileM,-(A7) ;File menu ID
_GetRMenu ;load it on heap
move.l (A7),FileMH(A5) ;copy handle for future ref.
clr.w -(A7) ;
_InsertMenu
clr.l -(A7) ;space for next handle
move.w #EditM,-(A7) ;Edit menu ID
_GetRMenu ;load it on heap
move.l (A7),EditMH(A5) ;copy handle for future ref.
clr.w -(A7) ;
_InsertMenu
clr.l -(A7) ;space for next handle
move.w #SCSIM,-(A7) ;SCSI menu ID
_GetRMenu ;load it on heap
move.l (A7),SCSIMH(A5) ;copy handle for future ref.
clr.w -(A7)
_InsertMenu
_DrawMenuBar
rts
ENDPROC
; PROC EventLoop
;
; This is where we process our events. Not much happening
; except some jump tables. We only process mouse down events
; and system events. All others ignored.
EventLoop PROC EXPORT
IMPORT (DownMouse,DownKey,Update,Activate):CODE
_SystemTask
clr.w -(A7)
move.w #EventMask,-(A7)
pea EventRec(A5)
; Note we unhighlight the menu only in the event loop so that
; long opporations like formating leave the menu bar selected
; until they have completed.
clr.w -(A7)
_HiLiteMenu
_GetNextEvent
move.w (A7)+,D0 ;boolean for is there an event
cmp.w #0,D0 ;if no event, loop back
beq.s EventLoop
movea.l #0,A0 ;clear register for jumptable
move.w EventRec.What(A5),A0 ;get type of event
adda.l A0,A0 ;multipy by 2 as offset table
;contains word length entries
lea JumpTable,A1
adda.l A1,A0 ;add offset to table address
adda.w (A0),A1 ;add offset for proc to table addr.
jmp (A1) ;jump to procedure
JumpTable
DATAREFS RELATIVE
dc.w EventLoop-JumpTable ;event #0 - null event
dc.w DownMouse-JumpTable ;event #1 - mouse-down
dc.w EventLoop-JumpTable ;event #2 - mouse-up
dc.w EventLoop-JumpTable ;event #3 - key-down
dc.w EventLoop-JumpTable ;event #4 - key-up
dc.w EventLoop-JumpTable ;event #5 - auto-key
dc.w EventLoop-JumpTable ;event #6 - update
dc.w EventLoop-JumpTable ;event #7 - disk-inserted
dc.w EventLoop-JumpTable ;event #8 - activate
dc.w EventLoop-JumpTable ;event #9 - n.a.
dc.w EventLoop-JumpTable ;event #10 - network
dc.w EventLoop-JumpTable ;event #11 - device driver
dc.w EventLoop-JumpTable ;Appl event #1
dc.w EventLoop-JumpTable ;Appl event #2
dc.w EventLoop-JumpTable ;Appl event #3
dc.w EventLoop-JumpTable ;Appl event #4
ENDPROC
; PROC DownMouse
;
; Procedure for handling mousedown events and figuring out which
; routine is used to handle the event.
DownMouse PROC Entry
IMPORT (MenuBar,SysProc):CODE
clr.w -(A7)
move.l EventRec.Point(A5),-(A7)
pea Window(A5)
_FindWindow
movea.l #0,A0 ;clear register
move.w (A7)+,A0 ;pop region number for mouse down
adda.l A0,A0 ;multiply by two as offset table has
;word entries
lea MouseTable,A1
adda.l A1,A0 ;add address of table to offset
adda.w (A0),A1 ;add offset of proc to table address
jmp (A1) ;jump to proc address
; Offset table for mouse down events.
MouseTable
DATAREFS RELATIVE
dc.w EventLoop-MouseTable ;in desk
dc.w MenuBar-MouseTable ;in menu bar
dc.w SysProc-MouseTable ;in system window
dc.w EventLoop-MouseTable ;in contents region
dc.w EventLoop-MouseTable ;in drag region
dc.w EventLoop-MouseTable ;in grow region
dc.w EventLoop-MouseTable ;in go away region
ENDPROC
; PROC MenuBar
;
; Subroutine for jumping to the correct menu. Put the menu
; number in A1 and the item number in A2. This procedure finds
; out which menu item was selected, calculated the correct
; address to jump to and jumps there.
MenuBar PROC ENTRY
IMPORT (QuitProc,UndoMI,CutMI,CopyMI,PasteMI):CODE
IMPORT (AppleMProc,SelAddrProc,ParamProc,EDefectProc):CODE
IMPORT (FDefectProc,FormatProc,MSenseProc,ResetProc):CODE
IMPORT (ClearMI):CODE
clr.w -(A7) ;space for longint from menu
move.l EventRec.Point(A5),-(A7)
_MenuSelect ;get the menu that was selected
movea.l #0,A1 ;clear A1
movea.l #0,A2 ;clear A2
move.w (A7)+,A1 ;menu id into A1
move.w (A7)+,A2 ;menu item into A2
cmpa.w #0,A1 ;movea doesn't set cond. codes
beq eventloop ;if menu ID=0 get another event
suba.l #AppleM+1,A1 ;convert menu id into menu #
;e.g. File menu becomes 0
cmpa.w #$FFFF,A1 ;was it the apple menu
beq AppleMProc ;yes, so go handle event
suba.l #1,A2 ;correct index (1st item = 0)
adda.l A1,A1 ;A1*2; table has word entries
adda.l A2,A2 ;A2*2; table has word entries
; Now calculate address to jump to by using the values in
; the offset tables.
lea MenuTable,A0
adda.l A0,A1 ;this gives in A1 the address of
;correct offset in MenuTable
adda.w (A1),A0 ;A0 now contains the address
;of the correct ItemTable
adda.l A0,A2 ;get correct entry in ItemTable
adda.w (A2),A0 ;add offset at this entry to
;address of ItemTable
jmp (A0) ;and jump to it!
; Offset table for each menu.
MenuTable
DATAREFS RELATIVE
dc.w FileMTable-MenuTable
dc.w EditMTable-MenuTable ;in system window
dc.w SCSIMTable-MenuTable ;in contents region
; ItemTables
; Offset table for each item in each menu.
FileMTable
dc.w QuitProc-FileMTable
EditMTable
dc.w UndoMI-EditMTable
dc.w 0
dc.w CutMI-EditMTable
dc.w CopyMI-EditMTable
dc.w PasteMI-EditMTable
dc.w ClearMI-EditMTable
SCSIMTable
dc.w SelAddrProc-SCSIMTable
dc.w ParamProc-SCSIMTable
dc.w EDefectProc-SCSIMTable
dc.w FormatProc-SCSIMTable
dc.w ResetProc-SCSIMTable
ENDPROC
;PROC SysProc
;
; Mouse down in a desk accessory. Go call _SystemClick.
SysProc PROC ENTRY
IMPORT (EventLoop):CODE
pea EventRec(A5)
move.l Window(A5),-(A7)
_SystemClick
jmp EventLoop
ENDPROC
;PROC QuitProc
;
; Procedure for quitting program.
QuitProc PROC ENTRY
_ExitToShell
ENDPROC
;PROC UndoMI
;
; Procedure to handle selection of the "Undo" menu item when a
; desk accessory controls the active window.
UndoMI PROC ENTRY
clr.w -(A7)
move.w #0,-(A7)
_SysEdit
adda.l #2,A7
jmp EventLoop
ENDPROC
;PROC CutMI
;
; Procedure to handle selection of the "Cut" menu item when a
; desk accessory controls the active window.
CutMI PROC ENTRY
clr.w -(A7)
move.w #2,-(A7)
_SysEdit
move.w (A7)+,D0
jmp EventLoop
ENDPROC
;PROC CopyMI
;
; Procedure to handle selection of the "Copy" menu item when a
; desk accessory controls the active window.
CopyMI PROC ENTRY
clr.w -(A7)
move.w #3,-(A7)
_SysEdit
move.w (A7)+,D0
jmp EventLoop
ENDPROC
;PROC PasteMI
;
; Procedure to handle selection of the "Paste" menu item when a
; desk accessory controls the active window.
PasteMI PROC ENTRY
clr.w -(A7)
move.w #4,-(A7)
_SysEdit
move.w (A7)+,D0
jmp EventLoop
ENDPROC
;PROC ClearMI
;
; Procedure to handle selection of the "Clear" menu item when a
; desk accessory controls the active window.
ClearMI PROC ENTRY
clr.w -(A7)
move.w #5,-(A7)
_SysEdit
move.w (A7)+,D0
jmp EventLoop
ENDPROC
; PROC AppleMProc
;
; This procedure handles menu events in the Apple menu. On
; entry, A2 has the item number of the menu item that was
; selected.
AppleMProc PROC ENTRY
IMPORT (DAName,QuickDraw):DATA
IMPORT (AboutProc,EventLoop):CODE
cmpa.l #AboutItem,A2 ;"About U2 Formatter" selected?
beq AboutProc ;yes, go put up dialog
; A desk accessory was selected, go instal it.
move.l QuickDraw.thePort(A5),MyPort(A5) ;save our port
move.l AppleMH(A5),-(A7) ;push handle for apple menu
move.w A2,-(A7) ;push item number hit
pea DAName(A5) ;push space for DA name
_GetItem ;get DA name
clr.w -(A7) ;space for driver reference #
pea DAName(A5) ;pass DA name
_OpenDeskAcc ;open DA
adda.l #2,A7
move.l MyPort(A5),-(A7) ;restore our port
_SetPort
jmp EventLoop
ENDPROC
; PROC AboutProc
;
; This procedure puts up our about U2 Formatter dialog box.
AboutProc PROC ENTRY
IMPORT (ButtonHit,QuickDraw):DATA
IMPORT (EventLoop,DefButton):CODE
clr.l -(A7) ;space for pointer to dialog
move.w #AboutRN,-(A7) ;About dialog resource number
pea DialogBuff(A5) ;pass address of dialog buffer
move.l #-1,-(A7) ;bring dialog window to front
_GetNewDialog
move.l (A7),DialogPort(A5) ;Save pointer to dialog rec
;note: pointer still left on
;stack for _SetPort trap
_SetPort
lea DialogBuff(A5),A4 ;pass address of dialog buffer
jsr DefButton
NotYet
clr.l -(A7) ;use standard filter proc
pea ButtonHit(A5) ;address of storage for item hit
_ModalDialog
cmpi.w #1,ButtonHit(A5) ;which item hit? is it "ok"?
bne NotYet ;no so loop back
move.l DialogPort(A5),-(A7) ;pass pointer to dialog rec
_CloseDialog
jmp EventLoop
ENDPROC
; PROC DefButton
;
; This procedure draws a rounded rectangle around our default
; button in a modal dialog. It gets passed the address of our
; dialog. It then gets the rectangle for the first item and
; draws a rounded rectangle around it.
DefButton PROC EXPORT
movem.l D0-D2/A0-A4,-(A7) ;save registers
; First we get the rectangle for item 1.
move.l A4,-(A7) ;push pointer for dialog
move.w #1,-(A7) ;push item number
pea ItemType(A5) ;address of space for item type
pea ItemHandle(A5) ;address of space for handle
pea ItemRect(A5) ;address of space for rectangle
_getDItem
move.w #3,-(A7) ;change pensize to 3X3
move.w #3,-(A7)
_PenSize
pea ItemRect(A5) ;make button smaller; all edges
move.w #-4,-(A7) ;moved in by 4 pixels
move.w #-4,-(A7)
_InsetRect
pea ItemRect(A5) ;draw boarder for default button
move.w #16,-(A7) ;curvature is 16 pixel in both
move.w #16,-(A7) ;directions
_FrameRoundRect
Done
movem.l (A7)+,D0-D2/A0-A4 ;restore registers
rts
ENDPROC
; PROC RadioHiLite
;
; This procedure selects the radio button that was chosen and
; deselects the radio button that was previously selected. It
; receives the old selected button in D0 and the new one in
; D1. It also receives the address of the dialog buffer in A4
; If this is the first time the procedure is being called
; for a given dialog box, it should be passed zero in D0 so that
; it doesn't try to deselect a radio button that is not selected.
; This procedure also checks to see that the button that was
; chosen was not the one that was already selected. If it is,
; it doesn't deselect it.
RadioHiLite PROC EXPORT
movem.l D0-D2/D6-D7/A0-A4,-(A7) ;save registers
move.w D0,D6 ;move radio button values to register
move.w D1,D7 ;that wont be trashed by traps
move.l A4,-(A7) ;get rectangle for radio button
move.w D7,-(A7)
pea ItemType(A5)
pea ItemHandle(A5)
pea ItemRect(A5)
_getDItem
; Duplicate top left hand point of rectangle into bottom right
; point of rectangle. They are now the same. Now add a
; different constantto each so that the circle in this rectangle
; is right in the middle of the radio button. Then invert this
; oval so it changes from white to black.
move.l ItemRect(A5),ItemRect+4(A5)
addi.l #$00070005,ItemRect(A5)
addi.l #$000D000B,ItemRect+4(A5)
pea ItemRect(A5)
_InvertOval
cmp.l D6,D7 ;is the radio button the same one that
beq Done ;was highlighted last time? If so,
;we are done.
tst.l D6 ;is this the first time called?
beq Done ;if so, D6=0 and we must quit
; Repeat the opporation for the old radio button, the one that
; was previously highlighted. This time _InvertOval will change
; it from black to white.
move.l A4,-(A7)
move.w D6,-(A7)
pea ItemType(A5)
pea ItemHandle(A5)
pea ItemRect(A5)
_getDItem
move.l ItemRect(A5),ItemRect+4(A5)
addi.l #$00070005,ItemRect(A5)
addi.l #$000D000B,ItemRect+4(A5)
pea ItemRect(A5)
_InvertOval
Done
movem.l (A7)+,D0-D2/D6-D7/A0-A4 ;restore registers
rts
ENDPROC
; PROC ErrorProc
;
; This procedure puts up an error dialog box. The dialog tells
; what the last SCSI command or trap was, what error occure and a
; possible explanation. All text is in STR resources. Trap names
; are given the resource number: "AX00" where X is the routine
; selector used by the SCSI Manager (IM, IV-295). SCSI commands
; are given the resource number: "X00" where X is the SCSI op
; code. These values are all in the FormatEqu.a file. Resource
; number for errors are of the form "AAXX" for traps where XX is
; the OSErr returned from the trap, or "10XX" for SCSI commands,
; where XX is the SCSI error reported by _SCSIComplete in the
; status parameter. Resource numbers for the "Most Probable
; Cause" strings are "BAXX" for traps and "20XX" for SCSI
; commands.
ErrorProc PROC EXPORT
IMPORT (Last_Cmd,Res,CompStat,CompMsg):DATA
; Get resource number for last command string and place a pointer
; to the string on the stack.
clr.l D4 ;place number for last command in D4
move.w Last_Cmd(A5),D4
lsl.l #8,D4 ;multipy by $100.
clr.l -(A7) ;space for handle
move.l #'STR ',-(A7) ;type of resource
move.w D4,-(A7) ;resource number
_GetResource ;get handle for last command string
move.l (A7)+,A0 ;pop handle into A0
move.l (A0),-(A7) ;dereference handle and push pointer
; Get resource number for error string and place a pointer to the
; string on the stack.
clr.l D3
move.w Res(A5),D3 ;if there was no OSError, Res=0
bne ErrorInTrap ;if Res = 0, error in SCSI command
move.w CompStat(A5),D3 ;SCSI error into D3
add.w #$1000,D3 ;add offset for SCSI command error
bra.s Continue
ErrorInTrap
add.w #$AA00,D3 ;add offset for trap error (OSError)
Continue
clr.l -(A7) ;space for handle
move.l #'STR ',-(A7) ;type of resource
move.w D3,-(A7) ;resource number
_GetResource ;get resource handle
move.l (A7)+,A0 ;pop handle into A0
move.l (A0),-(A7) ;dereference handle and push pointer
; Get resource number for most probable cause string and place a
; pointer to the string on the stack.
add.l #$1000,D3 ;add offset to error# to get cause#
clr.l -(A7) ;space for handle
move.l #'STR ',-(A7) ;type of resource
move.w D3,-(A7) ;resource number
_GetResource ;get resource handle
move.l (A7)+,A0 ;pop handle into A0
move.l (A0),-(A7) ;dereference handle and push pointer
clr.b StrBuff4(A5) ;make last string empty
pea StrBuff4(A5) ;pass pointer to empty string
_ParamText
move.w #133,-(A7) ;resource number for dialog
clr.l -(A7) ;use standard filter proc function
_NoteAlert
jmp EventLoop ;return to the event loop
ENDPROC
; PROC CountOff
;
; This procedure produces a delay equal to the number of ticks
; in the long word passed in D0.
CountOff PROC EXPORT
movem.l D0-D3/A0-A1,-(A7) ;save the registers
move.l D0,D3 ;move our value into a register that
;wont be trashed by the traps
clr.l -(A7) ;space for the current tick count
_TickCount
add.l (A7)+,D3 ;add our delay to the current tick
;count, this is when we stop
;waiting.
; Our loop to see if we have gone past the tick count we are
; waiting for.
NotYet
clr.l -(A7) ;space for number of ticks since reboot
_TickCount
cmp.l (A7)+,D3 ;is this as big as the number we are
;waiting for?
bgt NotYet ;if not, then repeat loop
movem.l (A7)+,D0-D3/A0-A1 ;restore registers
rts
ENDPROC
; PROC UnHiLite
;
; This procedure unhighlights an item in a dialog box to show
; that it cannot be selected. It receives the address of the
; dialog record in A4 and the item number to be unhighlighted in
; D0.
UnHiLite PROC EXPORT
movem.l D0-D2/A0-A1,-(A7) ;save the registers
move.l A4,-(A7) ;get the item rect for the item
move.w D0,-(A7) ;number that we were passed
pea ItemType(A5)
pea ItemHandle(A5)
pea ItemRect(A5)
_getDItem
move.l ItemHandle(A5),-(A7) ;pass the item handle
move.w #255,-(A7) ;pass flag for unhighlighting
_HiLiteControl
movem.l (A7)+,D0-D2/A0-A1 ;restore registers
rts
ENDPROC
; PROC ExtractNumb
;
; This procedure extracts the number value from an edit text item
; in a dialog box. It gets passed the item number in D0 and the
; address of the Dialog box record in A4. A3 contains a pointer
; to the long where output is to be placed and D3 contains the
; maximum value allowable.
ExtractNumb PROC EXPORT
movem.l D0-D2/A0-A1,-(A7) ;save registers
clr.l (A3) ;clear output long
; Get the handle for this item number.
move.l A4,-(A7) ;pass dialog record pointer
move.w D0,-(A7) ;pass item number
pea ItemType(A5)
pea ItemHandle(A5)
pea ItemRect(A5)
_getDItem
; Get the text from that dialog item. Move text into StrBuff1.
move.l ItemHandle(A5),-(A7)
pea StrBuff1(A5)
_GetIText
clr.l D0 ;get length of text out of first
move.b StrBuff1(A5),D0 ;byte and place it in D0
ble Exit ;if length is 0, we are done.
; Loop to remove all characters that aren't numbers. D1 is the
; index for the position being tested. D2 is the index for the
; last valid position.
lea StrBuff1(A5),A0 ;initialize A0 to point to string
moveq.l #1,D1
moveq.l #1,D2
Loop:
cmp.b #'0',(A0,D1.w) ;test next character
blt NotNumb
cmp.b #'9',(A0,D1.w)
bgt NotNumb
cmp.l D1,D2 ;if indeces are same, no move is
beq NoMove ;necessary
move.b (A0,D1.w),(A0,D2.w) ;move character
NoMove:
addq.l #1,D1 ;increment both pointers as last
addq.l #1,D2 ;character was a number
cmp.w D1,D0 ;reached the end of string?
bge Loop ;no
bra Convert ;yes
NotNumb
addq.w #1,D1 ;only increment test pointer
cmp.w D1,D0 ;reached the end of string?
bge Loop ;no
bra Convert ;yes
Convert:
subq.l #1,D2 ;make D2 into count byte
move.b D2,(A0) ;count byte into byte 1 of string
_StringToNum ;convert to hex value
move.l D0,(A3) ;move result to output
Default
cmp.l (A3),D3 ;is result greater than allowable
bge Exit ;no, we can exit
move.l D3,(A3) ;yes so use default value instead
Exit
movem.l (A7)+,D0-D2/A0-A1 ;restore registers
rts
ENDPROC
END